package autoFile.core.strategy;

import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;

import java.io.*;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: liuliwei
 * Date: 2017-08-16
 * Time: 下午4:22
 * Description: ${description}
 */
public class AbstractStrategy {
    /**
     * 方法主体
     *
     * @param path
     * @return
     * @throws IOException
     */
    protected static String getTemplateByFullPath(String path) throws IOException {
        FileReader fileReader = new FileReader(path);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        return getString(bufferedReader);
    }

    private static String getString(BufferedReader bufferedReader) throws IOException {
        StringBuilder ret = new StringBuilder();
        String temp;
        while ((temp = bufferedReader.readLine()) != null) {
            ret.append(temp);
        }
        return ret.toString();
    }


    String getTemplate(String path) throws IOException {
        Reader reader = new InputStreamReader(getInputTemplateInputStream(path));
        BufferedReader bufferedReader = new BufferedReader(reader);
        return getString(bufferedReader);
    }
    /**
     *
     * @param method
     * @param names 需要排除的类
     * @return
     */
    static String getParameterTypeAndName(Method method, String... names) {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        Class<?>[] parameterTypes = method.getParameterTypes();
        String[] parameterNames = u.getParameterNames(method);
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < parameterTypes.length; i++) {
            if(!classEquals(parameterTypes[i],names)){
                ret.append(convertParameterType(parameterTypes[i])).append(" ").append(parameterNames[i]);
                if (i < ((parameterTypes.length) - 1)) {
                    ret.append(",");
                }
            }
        }
        return ret.toString();
    }

    private static boolean classEquals(Class<?> parameterType, String[] classes) {
        if (classes==null||classes.length==0) {
            return false;
        }
        for (String aClass : classes) {
            if (parameterType.getName().contains(aClass)) {
                return true;
            }
        }
        return false;
    }

    static String getFinalParameterTypeAndName(Method method) {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        Class<?>[] parameterTypes = method.getParameterTypes();
        String[] parameterNames = u.getParameterNames(method);
        String ret = "";
        for (int i = 0; i < parameterTypes.length; i++) {
            ret += "final " +convertParameterType(parameterTypes[i]) + " " + parameterNames[i];
            if (i < ((parameterTypes.length) - 1)) {
                ret += ",";
            }
        }
        return ret;
    }

    private static String convertParameterType(Class<?> parameterType) {
        String pa = parameterType.getName();
        if (pa.contains(".")) {
            pa = pa.substring(pa.lastIndexOf(".") + 1);
        }
        return pa.replace("$","!");
    }

    /**
     * 需要排队名称
     * @param method
     * @param names
     * @return
     */
    protected static String getParameterNames(Method method,String ... names) {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] parameterNames = u.getParameterNames(method);
        if (names!=null&&names.length>0) {
            for (String name : names) {
                parameterNames= (String[]) ArrayUtils.removeElement(parameterNames, name);
            }
        }
        return Arrays.toString(parameterNames).substring(1, Arrays.toString(parameterNames).length() - 1);
    }

    public static void main(String[] args) throws IOException {
        String[] strings = {"dd","ddd"};
        strings= (String[]) ArrayUtils.removeElement(strings,"ddd");
        System.out.println(Arrays.toString(strings));
    }

    protected String getDbConstant(String simpleName, Method method) throws IOException {
        simpleName = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.LOWER_CAMEL).convert(simpleName);
        String methodName = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_CAMEL).convert(method.getName());
        String name = simpleName + methodName;
        return "GongDbConstants." + CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE).convert(name);
    }

    protected String getGongRpcConstant(String simpleName, Method method) throws IOException {
        simpleName = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.LOWER_CAMEL).convert(simpleName);
        String methodName = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_CAMEL).convert(method.getName());
        String name = simpleName + methodName;
        String pre = "public static final String ";
        String content = "REQ_" + CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE).convert(name);
        String suf = " = \"u." + name + "\";";
        String returnString = "GongRpcConstants." + content;
        String gongRpcConstant = pre + content + suf + "\n";
        return returnString;
    }

  List<Method> getPublicMethod(Class clazz) {
      Method[] declaredMethods = clazz.getDeclaredMethods();
      List<Method> returnList = Lists.newArrayList();
      for (Method declaredMethod : declaredMethods) {
          if (Modifier.isPublic(declaredMethod.getModifiers())) {
              returnList.add(declaredMethod);
          }
      }
      return returnList;
  }

    protected static String getBasicPath() {
        return getTemplateBasicPath()+ "/../../src/main/java/";
    }

    protected static String getTemplateBasicPath() {
        return Thread.currentThread().getContextClassLoader().getResource("").getPath();
    }

    /**
     * 封装成jar包之后
     * 可以这样得到文件数据
     * 不过文件要放在resource中相应位置
     * @param path
     * @return
     */
    protected InputStream getInputTemplateInputStream(String path) {

        return getClass().getResourceAsStream(path);
    }

}

